package ma.ensao.evalmetrics.interpretation;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import ma.ensao.evalmetrics.controller.MetriquesManager;
import ma.ensao.evalmetrics.controller.ProprieteManager;
import ma.ensao.evalmetrics.controller.ResultManager;
import ma.ensao.evalmetrics.controller.metrics.Calcule;
import ma.ensao.evalmetrics.model.Metriques;
import ma.ensao.evalmetrics.model.Propriete;
import ma.ensao.evalmetrics.model.ProprieteInt;
import ma.ensao.evalmetrics.model.Result;

import com.opensymphony.xwork2.ActionSupport;

public class ProprieteIntManager extends ActionSupport {
	
	private Long idp;
	private ResultManager resultmanager;
	private Result maresult;
	private MetriquesManager metriquesmanager = new MetriquesManager();
	private ProprieteManager proprietemanager = new ProprieteManager();
	private Calcule calcule = new Calcule();
	private Propriete propriete;
	private Metriques metric;
	private List<ProprieteInt> records;
	private String result;
	
	//
	private Long idresult;

	
	public String afficher() {
		
		records = new ArrayList<ProprieteInt>() ;
		resultmanager = new ResultManager();
		maresult = resultmanager.resultById(idresult);
		metric = metriquesmanager.list(idp).get(0);
		metric = calcule.calculMetrique(metric, maresult);
		propriete = proprietemanager.list(idp).get(0);
		propriete = calcule.calculPropriete(propriete);
		propriete.setId(idresult);
		
		ProprieteInt proprieteInt;

		proprieteInt = map(propriete,metric);
		records.add(proprieteInt);
		
		result="OK";

		return SUCCESS;
	}
	
	public static ProprieteInt map(Propriete oldprop,Metriques result){
		ProprieteInt prop = new ProprieteInt();
		
		prop.setId(oldprop.getId());
		prop.setSize(oldprop.getSize());
		prop.setComplexite(oldprop.getComplexite());
		prop.setHeritage(oldprop.getHeritage());
		prop.setEncapsulation(oldprop.getEncapsulation());
		prop.setAbstraction(oldprop.getAbstraction());
		prop.setMessage(oldprop.getMessage());
		prop.setCohesion(oldprop.getCohesion());
		prop.setCoupling(oldprop.getCoupling());
		prop.setInstabilite(oldprop.getInstabilite());
		prop.setDependence(oldprop.getDependence());
		//====== complexite interpretation : 
		double wmcInt;
		if(result.getCyclo()>=80){
			wmcInt=Math.pow(2,(30-result.getNOM())/10);
		}
		else if(50<=result.getCyclo() && result.getCyclo()<80){
			wmcInt=Math.pow(2,(20-result.getNOM())/30);
		}
		else if(30<=result.getCyclo() && result.getCyclo()<50){
			wmcInt=Math.pow(3,(15-result.getNOM())/15);
		}
		else{
			wmcInt = 3;
		}
		wmcInt = new BigDecimal(wmcInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		prop.setComplexiteInt(wmcInt);
		//====== size interpretation : 
		// SLOC ( LOC )
		double slocInt;
		if(result.getLOC()>70*result.getNOM()){
			slocInt=Math.pow(2,(70-(result.getLOC()/result.getNOM()))/21);
		}
		else{
			slocInt = 3;
		}
		slocInt = new BigDecimal(slocInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		// cloc
		double clocInt;
		if(result.getCLOC()>30*result.getNOM() ){
			clocInt=Math.pow(2,(70-(result.getCLOC()/result.getNOM()))/21);
		}
		else{
			clocInt = 3;
		}
		clocInt = new BigDecimal(clocInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		// nom
		double nomInt;
		if(result.getNOM()<=20 * (result.getClasses())){
			nomInt = 3;
		}
		else if( (20*result.getClasses()) < result.getNOM() && result.getNOM()<= (30 *result.getClasses())){
			nomInt = 2;
		}
		else if((30*result.getClasses())<result.getNOM() && result.getNOM()<=(60*result.getClasses())){
			nomInt =1;
		}
		else {
			nomInt = 0;
		}
		nomInt=new BigDecimal(nomInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		
		double sizeInt =  (wmcInt + clocInt + slocInt + nomInt )/4;
		prop.setSizeInt(sizeInt);
		
		// ======== Heritage interpretation 
		double ditInt;
		if(result.getDIT()<=5){
			ditInt=3;
		}
		else if(5<result.getDIT() && result.getDIT()<=6){
			ditInt = 2;
		}
		else if(6<result.getDIT() && result.getDIT()<=7){
			ditInt = 1;
		}
		else{
			ditInt = 0;
		}
		ditInt = new BigDecimal(ditInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		prop.setHeritageInt(ditInt);
		// ========= encapsulation 
		double ahfInt = 0;
		ahfInt = result.getAHF() * 3 ;
		ahfInt = new BigDecimal(ahfInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		prop.setEncapsulationInt(ahfInt);
		// ======== abstraction
		double absInt = 0;
		absInt = result.getAbs() * 3 ;
		absInt = new BigDecimal(absInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		prop.setAbstractionInt(absInt);
		// ==== instabilite  
		
		double instabInt;
		instabInt = 3-(2*((25-result.getI())/25));
		instabInt = new BigDecimal(instabInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		prop.setInstabiliteInt(instabInt);
		// ====  dependence 
		double dInt;
		dInt = 3-(2*((25-result.getD())/25));
		dInt = new BigDecimal(dInt ).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		prop.setDependenceInt(dInt);
		// ===== Message  not yet
		prop.setMessageInt(1.5);
		// ===== Cohesion not yet
		prop.setCohesionInt(1.5);
		// ===== coupling  not yet
		prop.setCouplingInt(1.5);
		
		return prop;
		
	}

	public Long getIdp() {
		return idp;
	}

	public void setIdp(Long idp) {
		this.idp = idp;
	}

	public List<ProprieteInt> getRecords() {
		return records;
	}

	public void setRecords(List<ProprieteInt> records) {
		this.records = records;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public Long getIdresult() {
		return idresult;
	}

	public void setIdresult(Long idresult) {
		this.idresult = idresult;
	}

	
	
}
